﻿using System;
using System.Windows.Input;

namespace NanoMvvm
{
    // TODO: add INotifyPropertyChanged watching mechanism to reduce calls to raise-can-execute
    public class CommandViewModel<T> : PropertyObservableBase where T : CommandBase
    {
        private string header;

        private string description;

        private bool tmpCanExecute;

        public CommandViewModel(string header, T command, string description = "")
        {
            Header = header;
            Command = command;
            Description = description;

            // RaiseCanExecuteChangedOnPropertyChanged = true;
        }

        public T Command { get; protected set; }

        public bool RaiseCanExecuteChangedOnPropertyChanged { get; set; }

        public string Header
        {
            get
            {
                return header;
            }

            set
            {
                SetProperty(ref header, value, () => Header);
            }
        }

        public string Description
        {
            get
            {
                return description;
            }

            set
            {
                SetProperty(ref description, value, () => Description);
            }
        }

        public bool LastCanExecute
        {
            get
            {
                return tmpCanExecute;
            }

            set
            {
                SetProperty(ref tmpCanExecute, value, () => LastCanExecute);
            }
        }

        protected override bool SetProperty<T1>(ref T1 field, T1 value, System.Linq.Expressions.Expression<Func<T1>> property)
        {
            var val = base.SetProperty(ref field, value, property);

            if (RaiseCanExecuteChangedOnPropertyChanged)
            {
                Command.RaiseCanExecuteChanged();
            }

            return val;
        }
    }

    public class CommandViewModel : CommandViewModel<CommandBase>
    {
        public CommandViewModel(string header, CommandBase command, string description = "") : base(header, command, description)
        {
        }
    }
}